/************************************************************************
This file is part of Polar4linux
Copyright (C) 2010-2011 Eric jrdn2
Portions Copyright (C) 2007 Matti Juvonen <mpj@iki.fi> (RS400 Tools)
Portions Copyright (C) 2006 Jani Hursti <jani.hursti@hut.fi>,
Portions Copyright (C) 2001-2003 Tom Oliveira e Silva

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
************************************************************************/

#include "basicexbuilder.h"

basicExBuilder::basicExBuilder(QWidget *parent) : QWidget(parent)
{
	setupUi(this);
	
	//basic ex
	connect(button_setExo, SIGNAL(clicked()), this, SLOT(setExos()));
	connect(button_getExo, SIGNAL(clicked()), this, SLOT(getExos()));
	connect(button_NewExo, SIGNAL(clicked()), this, SLOT(newExo()));
	connect(button_DeleteExo, SIGNAL(clicked()), this, SLOT(deleteExo()));
	
	connect(checkBox_z2, SIGNAL(clicked()), this, SLOT(enablez2()) );
	connect(checkBox_z3, SIGNAL(clicked()), this, SLOT(enablez3()) );
	connect(comboBoxZoneLimits, SIGNAL(currentIndexChanged ( int )), this, SLOT(set_display_style(int)) );
	connect(comboBoxZoneGuide, SIGNAL(currentIndexChanged ( int )), this, SLOT(set_display_style0(int)) );
	connect(tableWidgetExos, SIGNAL(cellClicked (int, int)), this, SLOT(savendisplayExercise(int)));
	
	tableWidgetExos->setColumnCount(2);
	QStringList labels;
	labels << tr("Name") << tr("Description");
	tableWidgetExos->setHorizontalHeaderLabels(labels);
	tableWidgetExos->horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);
	tableWidgetExos->verticalHeader()->hide();
	tableWidgetExos->setShowGrid(true);

	set_display_style(1);
	enableline1(true);
	enableline2(false);
	enableline3(false);
	currentDisplayedEx=-1;
	comboBoxZoneGuide->setCurrentIndex(1);
}

void basicExBuilder::associate(polar4linuxInternals *internals0)
{
	internals=internals0;
}



void basicExBuilder::getExos()
{
	//init_session();
	if (internals->IRDAok)
	{
		_getExos(internals->exos);
		//close_session();
	
		//tableWidgetExos->clear();
		for (int i=tableWidgetExos->rowCount()-1;i>=0;--i) tableWidgetExos->removeRow(i);
	
		for (int i=0;i<internals->exos.totalnum;i++)
		{
			QTableWidgetItem *name = new QTableWidgetItem((char*)internals->exos.exo[i].name);
			//name->setFlags(Qt::ItemIsEnabled);
			QTableWidgetItem *description = new QTableWidgetItem((char*)internals->exos.exo[i].description);
			//description->setFlags(Qt::ItemIsEnabled);
	
			int row = tableWidgetExos->rowCount();
			tableWidgetExos->insertRow(row);
			tableWidgetExos->setItem(row, 0, name);
			tableWidgetExos->setItem(row, 1, description);
		}
	}
}

void basicExBuilder::setExos()
{
	if (currentDisplayedEx!=-1 || internals->exos.totalnum == 0)
	{
		savendisplayExercise (currentDisplayedEx);
		//init_session();
		if (internals->IRDAok) _setExos(internals->exos);
		//close_session();
	}
}

void basicExBuilder::newExo()
{
	if (internals->exos.totalnum<10)
	{
		internals->exos.totalnum+=1;

		unsigned char name0[]="newExo";
		memcpy(internals->exos.exo[internals->exos.totalnum-1].name,name0,sizeof(name0));

		unsigned char name1[]="newDesc";
		memcpy(internals->exos.exo[internals->exos.totalnum-1].description,name1,sizeof(name1));

		QTableWidgetItem *name = new QTableWidgetItem((char*)internals->exos.exo[internals->exos.totalnum-1].name);
		//name->setFlags(Qt::ItemIsEnabled);

		QTableWidgetItem *description = new QTableWidgetItem((char*)internals->exos.exo[internals->exos.totalnum-1].description);
		//description->setFlags(Qt::ItemIsEnabled);

		int row = tableWidgetExos->rowCount();
		tableWidgetExos->insertRow(row);
		tableWidgetExos->setItem(row, 0, name);
		tableWidgetExos->setItem(row, 1, description);

		internals->exos.exo[internals->exos.totalnum-1].num_zones=1;
		internals->exos.exo[internals->exos.totalnum-1].active_zonesTargets=1;
		//currentDisplayedEx=exos.totalnum-1;

		//lineEdit_ExName->setText((char*)exos.exo[row].name);
		//lineEdit_ExDescription->setText((char*)exos.exo[row].description);
		savendisplayExercise(internals->exos.totalnum-1);
	}
}


void basicExBuilder::deleteExo()
{
	if (internals->exos.totalnum>=1)
	{
		internals->exos.totalnum-=1;

		memcpy(&internals->exos.exo[currentDisplayedEx],&internals->exos.exo[currentDisplayedEx+1],\
		(internals->exos.totalnum-currentDisplayedEx)*sizeof(polarLINUXio_basic_exercise));

		tableWidgetExos->removeRow(currentDisplayedEx);
		if (internals->exos.totalnum!=0) currentDisplayedEx=0;
		else  currentDisplayedEx=-1;
		displayExercise(currentDisplayedEx);
	}
}






void basicExBuilder::enablez2()
{
	polarLINUXio_basic_exercise* p = &internals->exos.exo[currentDisplayedEx];
	if (checkBox_z2->isChecked()==true)
	{
		p->num_zones=2;
		enableline2(true);
	}
	else
	{
		p->num_zones=1;
		enableline2(false);
		enableline3(false);
	}
}

void basicExBuilder::enablez3()
{
	polarLINUXio_basic_exercise* p = &internals->exos.exo[currentDisplayedEx];
	if (checkBox_z3->isChecked()==true && checkBox_z2->isChecked())
	{
		p->num_zones=3;
		enableline3(true);
	}
	else
	{
		p->num_zones=2;
		enableline3(false);
	}
}

void basicExBuilder::enableline1(bool val)
{
	widgetBounds1->setEnabled(val);
	widgetTarget1Min->setEnabled(val);
	widgetTarget1Max->setEnabled(val);
	labelTo1->setEnabled(val);
}

void basicExBuilder::enableline2(bool val)
{
	checkBox_z2->setChecked(val);
	widgetBounds2->setEnabled(val);
	widgetTarget2Min->setEnabled(val);
	widgetTarget2Max->setEnabled(val);
	labelTo2->setEnabled(val);
	checkBox_z3->setEnabled(val);
}

void basicExBuilder::enableline3(bool val)
{
	checkBox_z3->setEnabled(val);
	checkBox_z3->setChecked(val);
	widgetBounds3->setEnabled(val);
	widgetTarget3Min->setEnabled(val);
	widgetTarget3Max->setEnabled(val);
	labelTo3->setEnabled(val);
}


void basicExBuilder::set_display_style0(int pos)
{
	if (pos==1)
	{
		widgetBounds1->setStyle(timeDisplay);
		widgetBounds2->setStyle(timeDisplay);
		widgetBounds3->setStyle(timeDisplay);
	}
	else if (pos==2)
	{
		widgetBounds1->setStyle(floatDisplay);
		widgetBounds2->setStyle(floatDisplay);
		widgetBounds3->setStyle(floatDisplay);
	}
	else
	{
		widgetBounds1->setStyle(noneDisplay);
		widgetBounds2->setStyle(noneDisplay);
		widgetBounds3->setStyle(noneDisplay);
	}
}


void basicExBuilder::set_display_style(int pos)
{
	comboBoxZoneLimits->setCurrentIndex(pos);

	if (pos==0 || pos ==4) //free or own zone
	{
		widgetTarget1Min->setStyle(noneDisplay);
		widgetTarget2Min->setStyle(noneDisplay);
		widgetTarget3Min->setStyle(noneDisplay);
		widgetTarget1Max->setStyle(noneDisplay);
		widgetTarget2Max->setStyle(noneDisplay);
		widgetTarget3Max->setStyle(noneDisplay);
		labelTo1->setVisible(false);
		labelTo2->setVisible(false);
		labelTo3->setVisible(false);
	}
	else if (pos==1 || pos==2 || pos==3) //hr
	{
		widgetTarget1Min->setStyle(intDisplay);
		widgetTarget2Min->setStyle(intDisplay);
		widgetTarget3Min->setStyle(intDisplay);
		widgetTarget1Max->setStyle(intDisplay);
		widgetTarget2Max->setStyle(intDisplay);
		widgetTarget3Max->setStyle(intDisplay);
		labelTo1->setVisible(true);
		labelTo2->setVisible(true);
		labelTo3->setVisible(true);
	}
	else if(pos==5) //sportzone
	{
		widgetTarget1Min->setStyle(intDisplay);
		widgetTarget2Min->setStyle(intDisplay);
		widgetTarget3Min->setStyle(intDisplay);
		widgetTarget1Max->setStyle(noneDisplay);
		widgetTarget2Max->setStyle(noneDisplay);
		widgetTarget3Max->setStyle(noneDisplay);
		labelTo1->setVisible(false);
		labelTo2->setVisible(false);
		labelTo3->setVisible(false);
	}
	else if(pos==6) //speed
	{
		widgetTarget1Min->setStyle(floatDisplay);
		widgetTarget2Min->setStyle(floatDisplay);
		widgetTarget3Min->setStyle(floatDisplay);
		widgetTarget1Max->setStyle(floatDisplay);
		widgetTarget2Max->setStyle(floatDisplay);
		widgetTarget3Max->setStyle(floatDisplay);
		labelTo1->setVisible(true);
		labelTo2->setVisible(true);
		labelTo3->setVisible(true);
	}
	else if(pos==7) //time
	{
		widgetTarget1Min->setStyle(timeDisplay);
		widgetTarget2Min->setStyle(timeDisplay);
		widgetTarget3Min->setStyle(timeDisplay);
		widgetTarget1Max->setStyle(timeDisplay);
		widgetTarget2Max->setStyle(timeDisplay);
		widgetTarget3Max->setStyle(timeDisplay);
		labelTo1->setVisible(true);
		labelTo2->setVisible(true);
		labelTo3->setVisible(true);
	}
}




void basicExBuilder::savendisplayExercise (int row)
{
	//save last one if displayed
	if (currentDisplayedEx!=-1) saveExercise(currentDisplayedEx);
	displayExercise(row);
}

void basicExBuilder::displayExercise (int row)
{
	//change displayed exercise
	currentDisplayedEx = row;

	polarLINUXio_basic_exercise* p = &internals->exos.exo[row];

	comboBoxZoneGuide->setCurrentIndex(p->guideType);

	//same algorithm for time and speed
	widgetBounds1->setValue(p->zone1length/100,p->zone1length%100);
	widgetBounds2->setValue(p->zone2length/100,p->zone2length%100);
	widgetBounds3->setValue(p->zone3length/100,p->zone3length%100);

	//0x00=Nothing, 0x04=HR free, 0x14=HRtargets, 0x1C=ownzone, 0x18=sportzone, 0x24=speed,0x34=pace
	if (p->zones_type == 0x04) set_display_style(0);
	else if (p->zones_type == 0x14) {set_display_style(1);}
	else if (p->zones_type == 0x15) {set_display_style(2);}
	else if (p->zones_type == 0x16) {set_display_style(3);}//disfunct from polar
	else if (p->zones_type == 0x1C) set_display_style(4);
	else if (p->zones_type == 0x18) set_display_style(5);
	else if (p->zones_type == 0x24) set_display_style(6);
	else if (p->zones_type == 0x34) set_display_style(7);

	enableline1(p->num_zones>=1);
	enableline2(p->num_zones>=2);
	enableline3(p->num_zones>=3);

	//fc
	widgetTarget1Min->setValue(p->FC1min[0],p->FC1min[1]);
	widgetTarget2Min->setValue(p->FC2min[0],p->FC2min[1]);
	widgetTarget3Min->setValue(p->FC3min[0],p->FC3min[1]);

	widgetTarget1Max->setValue(p->FC1max[0],p->FC1max[1]);
	widgetTarget2Max->setValue(p->FC2max[0],p->FC2max[1]);
	widgetTarget3Max->setValue(p->FC3max[0],p->FC3max[1]);
	
	if (p->zones_type==0x34) //pace
	{
		int valmin,valmax;
		
		valmin = msb_lsb_to_decimal(p->FC1min[1],p->FC1min[0]);
		valmax = msb_lsb_to_decimal(p->FC1max[1],p->FC1max[0]);
		widgetTarget1Min->setValue(valmin/600,(valmin%600)/10 );
		widgetTarget1Max->setValue(valmax/600,(valmax%600)/10 );
		
		valmin = msb_lsb_to_decimal(p->FC2min[1],p->FC2min[0]);
		valmax = msb_lsb_to_decimal(p->FC2max[1],p->FC2max[0]);
		widgetTarget2Min->setValue(valmin/600,(valmin%600)/10 );
		widgetTarget2Max->setValue(valmax/600,(valmax%600)/10 );
	
		valmin = msb_lsb_to_decimal(p->FC3min[1],p->FC3min[0]);
		valmax = msb_lsb_to_decimal(p->FC3max[1],p->FC3max[0]);
		widgetTarget3Min->setValue(valmin/600,(valmin%600)/10 );
		widgetTarget3Max->setValue(valmax/600,(valmax%600)/10 );
	}
	else if (p->zones_type==0x24) //speed
	{
		widgetTarget1Min->setValue(p->FC1min[1],(100*p->FC1min[0])/255);
		widgetTarget2Min->setValue(p->FC2min[1],(100*p->FC2min[0])/255);
		widgetTarget3Min->setValue(p->FC3min[1],(100*p->FC3min[0])/255);

		widgetTarget1Max->setValue(p->FC1max[1],(100*p->FC1max[0])/255);
		widgetTarget2Max->setValue(p->FC2max[1],(100*p->FC2max[0])/255);
		widgetTarget3Max->setValue(p->FC3max[1],(100*p->FC3max[0])/255);
	}
	
	internals->basic_graph->setWorkingExercise(&internals->exos.exo[currentDisplayedEx]);
	view->removeGraphs();
	view->addGraph(internals->basic_graph);
	view->plotPage();
}


void basicExBuilder::saveExercise (int current)
{
	polarLINUXio_basic_exercise* p = &internals->exos.exo[current];

	p->number = currentDisplayedEx;
	
	std::string name = tableWidgetExos->item(current,0)->text().toStdString();
	std::string description = tableWidgetExos->item(current,1)->text().toStdString();
	
	//crop size
	name.resize (10,' ');
	description.resize (20,' ');
	memcpy(p->name,name.c_str(),10);
	memcpy(p->description,description.c_str(),20);
	tableWidgetExos->item(current,0)->setText(QString(name.c_str()));
	tableWidgetExos->item(current,1)->setText(QString(description.c_str()));

	p->num_zones = 1+(char)checkBox_z2->isChecked()+(char)checkBox_z3->isChecked(); //number of zones, up to 3
	//p->active_zonesTargets=(char)checkBoxL1->isChecked()+(char)checkBoxL2->isChecked()+(char)checkBoxL3->isChecked(); //
	p->active_zonesTargets=p->num_zones;
	p->guideType = comboBoxZoneGuide->currentIndex();
	//printf("                guidetype %x\n",p->guideType);

	if (comboBoxZoneLimits->currentIndex()==0) p->zones_type = 0x04;
	else if (comboBoxZoneLimits->currentIndex()==1) p->zones_type = 0x14;
	else if (comboBoxZoneLimits->currentIndex()==2) p->zones_type = 0x15;  
	else if (comboBoxZoneLimits->currentIndex()==3) p->zones_type = 0x16;  
	else if (comboBoxZoneLimits->currentIndex()==4) p->zones_type = 0x1C;
	else if (comboBoxZoneLimits->currentIndex()==5) p->zones_type = 0x18;
	else if (comboBoxZoneLimits->currentIndex()==6) p->zones_type = 0x24;
	else if (comboBoxZoneLimits->currentIndex()==7) p->zones_type = 0x34;

	p->zone1length=100*widgetBounds1->valueLeft()+widgetBounds1->valueRight();
	p->zone2length=100*widgetBounds2->valueLeft()+widgetBounds2->valueRight();
	p->zone3length=100*widgetBounds3->valueLeft()+widgetBounds3->valueRight();

	if (p->zones_type==0x34) //pace
	{
	  int value;
		value = widgetTarget1Min->valueLeft()*600+widgetTarget1Min->valueRight()*10;
	  int_to_msb_lsb(value, &p->FC1min[1], &p->FC1min[0]);

		value = widgetTarget1Max->valueLeft()*600+widgetTarget1Max->valueRight()*10;
	  int_to_msb_lsb(value, &p->FC1max[1], &p->FC1max[0]);
	  
		value = widgetTarget2Min->valueLeft()*600+widgetTarget2Min->valueRight()*10;
	  int_to_msb_lsb(value, &p->FC2min[1], &p->FC2min[0]);

		value = widgetTarget2Max->valueLeft()*600+widgetTarget2Max->valueRight()*10;
	  int_to_msb_lsb(value, &p->FC2max[1], &p->FC2max[0]);
	  
		value = widgetTarget3Min->valueLeft()*600+widgetTarget3Min->valueRight()*10;
	  int_to_msb_lsb(value, &p->FC3min[1], &p->FC3min[0]);

		value = widgetTarget3Max->valueLeft()*600+widgetTarget3Max->valueRight()*10;
	  int_to_msb_lsb(value, &p->FC3max[1], &p->FC3max[0]);
	}
	else if (p->zones_type==0x24) //speed
	{
	  p->FC1min[0] = widgetTarget1Min->valueRight()*2.55;
	  p->FC1min[1] = widgetTarget1Min->valueLeft();
	  
	  p->FC2min[0] = widgetTarget2Min->valueRight()*2.55;
	  p->FC2min[1] = widgetTarget2Min->valueLeft();
	  
	  p->FC3min[0] = widgetTarget3Min->valueRight()*2.55;
	  p->FC3min[1] = widgetTarget3Min->valueLeft();
	  
	  p->FC1max[0] = widgetTarget1Max->valueRight()*2.55;
	  p->FC1max[1] = widgetTarget1Max->valueLeft();
	  
	  p->FC2max[0] = widgetTarget2Max->valueRight()*2.55;
	  p->FC2max[1] = widgetTarget2Max->valueLeft();
	  
	  p->FC3max[0] = widgetTarget3Max->valueRight()*2.55;
	  p->FC3max[1] = widgetTarget3Max->valueLeft();
	}
	else
	{
	  p->FC1min[0] = widgetTarget1Min->valueLeft();
	  p->FC1min[1] = widgetTarget1Min->valueRight();
	  
	  p->FC2min[0] = widgetTarget2Min->valueLeft();
	  p->FC2min[1] = widgetTarget2Min->valueRight();
	  
	  p->FC3min[0] = widgetTarget3Min->valueLeft();
	  p->FC3min[1] = widgetTarget3Min->valueRight();
	  
	  p->FC1max[0] = widgetTarget1Max->valueLeft();
	  p->FC1max[1] = widgetTarget1Max->valueRight();
	  
	  p->FC2max[0] = widgetTarget2Max->valueLeft();
	  p->FC2max[1] = widgetTarget2Max->valueRight();
	  
	  p->FC3max[0] = widgetTarget3Max->valueLeft();
	  p->FC3max[1] = widgetTarget3Max->valueRight();
	}
}
  